home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / system / ced_adds.zip / NEWCD.ASM < prev    next >
Assembly Source File  |  1995-10-30  |  11KB  |  394 lines

  1.     ;    CD         Ver. 1.0
  2.     ;
  3.     ;    This program replaces COMMAND.COM's CD. Basically, it works
  4.     ;    the same way. The current directory is changed to the pathname
  5.     ;    given as the only parameter. But, in case of an error, this new
  6.     ;    CD-command behaves differently: If the given parameter starts 
  7.     ;    with '\' or '/', the current directory isn't changed and the
  8.     ;    program aborts with an error message.
  9.     ;    If the parameter only specifies part of a pathname and such a
  10.     ;    subdirectory doesn't exist in the current directory, the
  11.     ;    environement variable CDPATH is evaluated. This variable
  12.     ;    specifies a list of subdirectories, separated by ';', in which
  13.     ;    we have to look for the directory to change to.
  14.     ;    If we still aren't successfull in changing to that directory,
  15.     ;    it's time for an error message.
  16.     ;    The program, once loaded, stays in RAM and works as an
  17.     ;    extension of the command interpreter.
  18.     ;    The user may specify if the command CD without a parameter
  19.     ;    changes to the root directory or prints the pathname of the
  20.     ;    current directory.
  21.     ;
  22.     ;    Copyright (C) 1987 by Urs Zurbuchen, Switzerland
  23.     ;
  24.     ;        You may freely distribute this program unless you
  25.     ;        include the sources and don't touch this header.
  26.     ;        Commercial usage is prohibited.
  27.     ;
  28.     ;    Requirements:
  29.     ;        This program requires that the command editor CED
  30.     ;        (by C.J. Dunford) is installed.
  31.     ;
  32.     ;    Restrictions:
  33.     ;        The environement variable is evaluated when the program
  34.     ;        is loaded. Changes to the environement after the
  35.     ;        program is loaded into memory are NOT recognized.
  36.     ;        CDPATH may not be longer than CDLENGTH characters. You
  37.     ;        can change this value in the sources below.
  38.     ;
  39.     ;    Usage:        CD
  40.     ;            CD pathname
  41.     ;
  42.     ;    Installation:    NEWCD {r | p}
  43.     ;                r: change to root
  44.     ;                p: print current directory
  45.     ;                Default is r
  46.     ;
  47.     ;    Assembly:    MASM newcd;
  48.     ;            LINK newcd;
  49.     ;            EXE2BIN newcd newcd.com
  50.     ;
  51.     ;    Author:        Urs Zurbuchen
  52.     ;
  53.     ;    Date:        February 15, 1987
  54.     ;
  55.     ;    Revisions:
  56.     ;        Date    Who        What
  57.     ;
  58.     ;----------------------------------------------------------------------
  59.  
  60.     ; adjust the following global according to the processor used
  61. is_8088    equ    0            ; you won't have those fancy '286
  62.                     ; instructions if true
  63.     if    is_8088
  64.         .8086
  65.     else
  66.         .286c            ; this requires MASM 4.0
  67.     endif
  68.  
  69.  
  70.     ; some global constants
  71. cr    equ    13            ; CarriageReturn
  72. lf    equ    10            ; LineFeed
  73. space    equ    32            ; (what do you guess :-)
  74. tab    equ     9            ; Tabulator
  75.  
  76.     ; definitions for the CED interface
  77. ced    equ    0ffh            ; special DOS function for CED services
  78. enqueue    equ    0            ; Subfunction to CED: enqueue command
  79. dequeue    equ    1            ; Subfunction to CED: dequeue command
  80. ced_dos    equ    1            ; CED parameter: command at DOS prompt
  81. ced_usr    equ    2            ; CED parameter: command in user prg
  82.  
  83.     ; configurable constant
  84. cdlength equ    255            ; max. string length of CDPATH
  85.  
  86.     ; here follows the program section
  87. cseg    segment    para public 'code'
  88.     assume    cs:cseg, ds:cseg, es:cseg
  89.  
  90.     ; initialization
  91.     org    100h
  92.  
  93.     ;-----------------------
  94.     ; Installation procedure
  95.     ;-----------------------
  96. main    proc    far
  97.     jmp    install            ; go to installation
  98.  
  99.     ; datastructures
  100. pwd:    db    0            ; 0: change to root
  101.                     ; 1: print current dir
  102. flag:    db    0            ; 0: partial pathname
  103.                     ; 1: pathname starts with '\' or '/'
  104. root:    db    '\',0            ; pathname for the root
  105. path:    db    67 dup (?)        ; working-storage for pathnames
  106. work:    db    100 dup (?)        ; working-storage (give it some reserves)
  107. cdpath:    db    cdlength + 1 dup (?)    ; CDPATH environement
  108.  
  109.     ; error messages
  110. msg1$    db    'cd: directory not found', cr, lf, '$'
  111. msg2$    db    'cd: HELP! HELP!  Cannot change to root directory', cr, lf, '$'
  112. msg3$    db    'cd: Cannot get current directory', cr, lf, '$'
  113. msg4$    db    'cd: Too many parameters', cr, lf, '$'
  114.  
  115.     ;-----------------
  116.     ; the CD procedure
  117.     ;-----------------
  118. newcd    proc    far
  119.     mov    byte ptr [si],cr    ; null out the users input
  120.     mov    bp,dx
  121.     push    ds            ; save data segment
  122.     pop    es
  123.     push    cs            ; set data segment context
  124.     pop    ds
  125.  
  126. cd_1:    mov    al,byte ptr es:[bp]    ; test for parameters
  127.     inc    bp
  128.     cmp    al,cr            ;   end of input reached ?
  129.     jz    cd_noparam
  130.     cmp    al,space        ;   leading spaces and tabs are ok
  131.     jz    cd_1
  132.     cmp    al,tab
  133.     jz    cd_1
  134.     jmp    cd_normal        ;   any other char inidicates pathname
  135.  
  136. cd_noparam:
  137.     cmp    byte ptr [pwd],1    ; true, if we have to print current dir
  138.     jz    cd_prcur
  139.  
  140.                     ; change current dir to root
  141.     mov    dx,offset root        ; ds:dx points to pathname for root
  142.     mov    ah,3bh            ; change current directory
  143.     int    21h
  144.     jnc    cd_nopara_1        ; avoid 'out of range'
  145.     jmp    err_trouble        ; you're in real trouble if this
  146.                     ; doesn't work
  147. cd_nopara_1:
  148.     jmp    cd_end
  149.  
  150. cd_prcur:                ; print current directory
  151.     mov    si,offset path        ; ds:si points to storage for pathname
  152.     mov    ah,19h            ; get current drive
  153.     int    21h
  154.     add    al,'A'            ; change to human readable characters
  155.     mov    ah,':'
  156.     mov    word ptr [si],ax    ; save drive name for print
  157.     inc    si
  158.     inc    si
  159.     mov    byte ptr [si],'\'    ; we don't get the first \ from DOS
  160.     inc    si            ; so we have to insert it
  161.     mov    dl,0            ; we'd like the current drive
  162.     mov    ah,47h            ; get current directory
  163.     int    21h
  164.     jnc    cd_prcur_1        ; avoid 'out of range'
  165.     jmp    err_getcurrent        ; can't imagine an error, but nobody's
  166.                     ; perfect
  167. cd_prcur_1:
  168.     mov    bx,1            ; file handle is standard output
  169.     mov    dx,offset path        ; start of text to print
  170.     xor    cx,cx            ; get length of string to print
  171.     mov    bp,dx
  172. cd_pr1:    inc    cx            ; one char is always there ('\')
  173.     inc    bp            ; test next (!) character
  174.     cmp    byte ptr ds:[bp],0    ; end of string is indicated by zero
  175.     jnz    cd_pr1
  176.     mov    ah,40h            ; write to a file or device
  177.     int    21h            ; print the string
  178.     jmp    cd_end            ; no test for error
  179.  
  180. cd_normal:                ; test for additional parameters
  181.     mov    di,offset path        ; init pointers
  182.     mov    cx,0
  183.     cmp    al,'\'            ; we have to know if the parameter
  184.     jz    cd_mark            ; starts with '\' or '/', or if it's
  185.     cmp    al,'/'            ; only a partial pathname
  186.     jnz    cd_2
  187. cd_mark: mov    byte ptr [flag],1
  188.  
  189. cd_2:    mov    byte ptr [di],al    ; save parameter
  190.     inc    di
  191.     inc    cx            ;   compute length of parameter in CX
  192.     mov    al,byte ptr es:[bp]    ;   get next character
  193.     inc    bp
  194.     cmp    al,cr            ;   end of input reached ?
  195.     jz    cd_cd
  196.     cmp    al,space        ;   space and tab are delimiters
  197.     jz    cd_3
  198.     cmp    al,tab
  199.     jz    cd_3
  200.     jmp    cd_2            ;   any other char belongs to pathname
  201.         
  202. cd_3:    mov    al,byte ptr es:[bp]    ; test for additional parameters
  203.     inc    bp
  204.     cmp    al,cr            ;   end of input reached ?
  205.     jz    cd_cd
  206.     cmp    al,space        ;   space and tab are ok at the tail
  207.     jz    cd_3
  208.     cmp    al,tab
  209.     jz    cd_3
  210.     jmp    err_toomany        ;   any other char is bad
  211.  
  212. cd_cd:    mov    byte ptr [di], 0    ; change pathname to ASCIIZ
  213.     mov    dx,offset path        ; ds:dx points to pathname
  214.     mov    ah,3bh            ; change current directory
  215.     int    21h
  216.     jnc    cd_end            ; exit, if no error occurs
  217.     cmp    byte ptr [flag],0    ; true if partial pathname
  218.     jnz    err_invalidir        ; full pathname leads to error
  219.  
  220.     push    ds            ; update es. now, we can use the
  221.     pop    es            ; string commands
  222.     mov    bp,offset cdpath    ; ds:bp points to next path in CDPATH
  223.     mov    si,offset path        ; ds:si points to parameter
  224.  
  225. cd_path:    ; try each entry in CDPATH as first part of the pathname
  226.         ; we copy the next entry in CDPATH to the working-storage
  227.         ; and append the actual parameter (the partial pathname)
  228.  
  229.     cmp    byte ptr ds:[bp],0    ; end of CDPATH is indicated by zero
  230.     jz    err_invalidir        ; I'm sorry, but I can't find that dir
  231.     mov    di,offset work        ; es:si points to working-storage
  232. cd_copy:
  233.     mov    al,byte ptr es:[bp]    ; copy entry in CDPATH
  234.     cmp    al,0            ;    end reached?
  235.     jz    cd_p1
  236.     cmp    al,';'            ;    end is indicated by zero or ';'
  237.     jz    cd_p1
  238.     stosb
  239.     inc    bp
  240.     jmp    cd_copy
  241.  
  242. cd_p1:    inc    bp            ; adjust pointer
  243.     mov    byte ptr [di],'\'    ; insert delimiter
  244.     inc    di
  245.     push    cx
  246.     push    si
  247.     repnz    movsb            ; append parameter
  248.     pop    si
  249.     pop    cx
  250.     mov    byte ptr [di],0        ; mark end
  251.     mov    dx,offset work        ; ds:dx points to the pathname
  252.     mov    ah,3bh
  253.     int    21h
  254.     jc    cd_path            ; repeat if still no valid directory
  255.  
  256. cd_end:    mov    byte ptr [flag],0    ; reset flag
  257.     ret                ; exit to CED
  258.  
  259. newcd    endp
  260.  
  261.  
  262.     ;--------------
  263.     ; error handler
  264.     ;--------------
  265. error    proc    near
  266. err_trouble:    ; you're in real trouble if we can't change to the root
  267.         ; I hope you have a real good 'disk doctor'
  268.     mov    dx,offset msg2$
  269.     jmp    err_common
  270.  
  271. err_getcurrent:    ; can't get the current directory's pathname
  272.         ; This isn't much better as the above
  273.     mov    dx,offset msg3$
  274.     jmp    err_common
  275.  
  276. err_toomany:    ; you specified too many parameters (only one allowed)
  277.     mov    dx,offset msg4$
  278.     jmp    err_common
  279.  
  280. err_invalidir:    ; you specified an invalid pathname
  281.     mov    dx,offset msg1$
  282.  
  283. err_common:                ; common point for error output
  284.     mov    ah,9            ; print string
  285.     int    21h
  286.     jmp    cd_end
  287.  
  288. error    endp
  289.  
  290.  
  291.     ;-------------------------------------------------------------------
  292.     ; This is the installation routine. It queues the two commands above
  293.     ; into the CED command editor. It terminates but leaves the command
  294.     ; routines resident.
  295.     ;-------------------------------------------------------------------
  296. install:
  297.     push    cs
  298.     pop    ds
  299.     push    ds
  300.     pop    es
  301.  
  302.     mov    ah,ced            ; request CED service from DOS
  303.     mov    al,enqueue        ; enqueue a new command
  304.     mov    bl,ced_dos        ; CD is only active at DOS prompt
  305.     mov    si,offset cd$        ; pointer to command name
  306.     mov    di,offset newcd        ; pointer to service routine
  307.     int    21h
  308.     jnc    inst_ok            ; no error: exit
  309.  
  310.     mov    dx, offset msg_inst1$    ; only error 8 is possible here
  311. inst_err:
  312.     mov    ah, 9            ; print string
  313.     int    21h
  314.     int    20h            ; exit without staying resident
  315.  
  316. inst_ok:
  317.     push    ds
  318.     mov    si,2ch            ; ds:si points to environement
  319.     mov    ds,word ptr [si]
  320.     mov    si,0
  321.     mov    di,offset cdpath    ; es:di points to space for CDPATH string
  322.     mov    cx,0
  323.  
  324. inst_search:                ; search for environement variable CDPATH
  325.     cmp    byte ptr [si],0        ; test for end of environement string
  326.     jz    inst_end
  327.     mov    bp,offset cdpath$    ; name of environement variable
  328.  
  329. inst_loop:                ; compare an environement entry with
  330.     lodsb                ; the variable name
  331.     inc    bp
  332.     cmp    al,byte ptr es:[bp-1]
  333.     jnz    inst_skip
  334.     cmp    al,'='
  335.     jnz    inst_loop
  336.     jmp    inst_copy
  337.  
  338. inst_skip:                ; skip to next entry
  339.     inc    si
  340.     cmp    byte ptr [si-1],0
  341.     jnz    inst_skip
  342.     jmp    inst_search
  343.  
  344. inst_copy:                ; copy definition
  345.     lodsb                ; get a char
  346.     stosb
  347.     inc    cx            ; max. string length is cdlength
  348.     cmp    cx,cdlength
  349.     jnc    inst_end
  350.     or    al,al            ; end reached? (marked by zero)
  351.     jnz    inst_copy        ; no: copy more
  352.  
  353. inst_end:
  354.     mov    byte ptr [di],0        ; mark end of CDPATH
  355.     pop    ds
  356.  
  357.     mov    cx,0
  358.     mov    bp,[80h]
  359.     mov    cl,byte ptr es:[bp]    ; any parameter given?
  360.     jcxz    inst_tsr        ; no: exit without changing the flag
  361.  
  362. inst_para:
  363.     mov    al,es:[bp+1]        ; leading spaces and tabs are ok
  364.     inc    bp
  365.     cmp    al,space
  366.     jz    inst_para
  367.     cmp    al,tab
  368.     jz    inst_para
  369.     or    al,20h            ; change into lower case
  370.     cmp    al,'p'            ; p means 'print current dir'
  371.     jz    inst_print
  372.     loopnz    inst_para
  373.     jmp    inst_tsr        ; don't change flag: 'go to root'
  374.  
  375. inst_print:
  376.     mov    byte ptr [pwd],1    ; set flag to 'print current dir'
  377.  
  378. inst_tsr:
  379.     mov    dx,offset install    ; ok: terminate/resident
  380.     int    27h
  381. main    endp
  382.  
  383.     ; messages for installation procedure
  384. msg_inst1$ db    'install cd: CED command list full', cr, lf, '$'
  385.  
  386.     ; command name
  387. cd$    db    'cd', cr
  388.  
  389.     ; environement variable name
  390. cdpath$    db    'CDPATH='
  391.  
  392. cseg    ends
  393.     end    main
  394.